import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_reader/main.dart';
import 'package:flutter_reader/model/article.dart';
import 'package:flutter_reader/model/chapter.dart';
import 'package:flutter_reader/ui/reader/reader_config.dart';
import 'package:flutter_reader/ui/reader/reader_menu.dart';
import 'package:flutter_reader/ui/reader/reader_view.dart';
import 'package:flutter_reader/utils/request.dart';
import 'package:flutter_reader/utils/screen.dart';
import 'package:flutter_reader/utils/toast.dart';

enum PageJumpType { stay, firstPage, lastPage }

class ReaderPage extends StatefulWidget {
  final int articleId;
  ReaderPage({this.articleId});

  @override
  _ReaderPageState createState() => _ReaderPageState();
}

class _ReaderPageState extends State<ReaderPage> with RouteAware {
  int pageIndex = 0;
  bool isShowMenu = false;
  PageController pageController = PageController(keepPage: false);
  bool isLoading = false;

  Article preArticle;
  Article curArticle;
  Article nextArticle;

  List<Chapter> chapters = [];

  double topSafeHeight = 0;

  @override
  void initState() {
    super.initState();
    pageController.addListener(onScroll);

    setupReaderData();
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    routeObserver.subscribe(this, ModalRoute.of(context));
  }

  @override
  void didPop() {
    super.didPop();
    SystemChrome.setEnabledSystemUIOverlays(
        [SystemUiOverlay.top, SystemUiOverlay.bottom]);
  }

  @override
  void dispose() {
    pageController.dispose();
    routeObserver.unsubscribe(this);
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: AnnotatedRegion(
        value: SystemUiOverlayStyle.dark,
        child: Stack(
          children: [
            Positioned(
                left: 0,
                top: 0,
                right: 0,
                bottom: 0,
                child: Image.asset('img/read_bg.png', fit: BoxFit.cover)),
            _buildPageView(),
            _buildMenu(),
          ],
        ),
      ),
    );
  }

  // 阅读视图
  Widget _buildPageView() {
    if (curArticle == null) {
      return Container(child: Text('未加载到章节信息...'));
    }

    int itemCount = (preArticle != null ? preArticle.pageCount : 0) +
        curArticle.pageCount +
        (nextArticle != null ? nextArticle.pageCount : 0);
    return PageView.builder(
      physics: BouncingScrollPhysics(),
      controller: pageController,
      itemCount: itemCount,
      itemBuilder: _buildPage,
      onPageChanged: _onPageChanged,
    );
  }

  // 阅读界面
  Widget _buildPage(BuildContext context, int index) {
    var page = index - (preArticle != null ? preArticle.pageCount : 0);
    var article;
    if (page > this.curArticle.pageCount) {
      // 到达下一章
      article = preArticle;
      page = preArticle.pageCount - 1;
    } else {
      article = this.curArticle;
    }

    return GestureDetector(
      onTapUp: (TapUpDetails details) {
        _onTap(details.globalPosition);
      },
      child: ReaderView(
          article: article, page: page, topSafeHeight: topSafeHeight),
    );
  }

  // 翻页改变回调
  void _onPageChanged(int index) {
    var page = index - (preArticle != null ? preArticle.pageCount : 0);
    if (page < curArticle.pageCount && page >= 0) {
      setState(() {
        pageIndex = page;
      });
    }
  }

  // 点击页面视图
  void _onTap(Offset position) async {
    double xRate = position.dx / Screen.width;
    if (xRate > 0.33 && xRate < 0.66) {
      SystemChrome.setEnabledSystemUIOverlays(
          [SystemUiOverlay.top, SystemUiOverlay.bottom]);
      setState(() {
        isShowMenu = true;
      });
    } else if (xRate >= 0.66) {
      _nextPage();
    } else {
      _previousPage();
    }
  }

  // 下一页
  void _nextPage() {
    if (pageIndex >= curArticle.pageCount - 1 &&
        curArticle.nextArticleId == 0) {
      Toast.show('已经是最后一页了');
      return;
    }
    pageController.nextPage(
        duration: Duration(milliseconds: 250), curve: Curves.easeOut);
  }

  // 上一页
  void _previousPage() {
    if (pageIndex == 0 && curArticle.preArticleId == 0) {
      Toast.show('已经是第一页了');
      return;
    }
    pageController.previousPage(
        duration: Duration(milliseconds: 250), curve: Curves.easeOut);
  }

  // 菜单视图
  Widget _buildMenu() {
    if (!isShowMenu) {
      return Container();
    }
    return ReaderMenu(
      chapters: chapters,
      articleIndex: curArticle.index,
      onTap: _hideMenu,
      onPreviousArticle: () =>
          resetContent(curArticle.preArticleId, PageJumpType.firstPage),
      onNextArticle: () =>
          resetContent(curArticle.nextArticleId, PageJumpType.firstPage),
      onToggleChapter: (Chapter chapter) =>
          resetContent(chapter.id, PageJumpType.firstPage),
    );
  }

  // 隐藏菜单界面
  void _hideMenu() {
    SystemChrome.setEnabledSystemUIOverlays([]);
    setState(() {
      this.isShowMenu = false;
    });
  }

  // 滚动切换章节
  void onScroll() {
    var page = pageController.offset / Screen.width;
    var nextArticlePage =
        curArticle.pageCount + (preArticle != null ? preArticle.pageCount : 0);
    if (page >= nextArticlePage) {
      print('---> 到达下个章节: ${nextArticle.title}');
      preArticle = curArticle;
      curArticle = nextArticle;
      nextArticle = null;
      pageIndex = 0;
      pageController.jumpToPage(preArticle.pageCount);
      loadNextArticle(curArticle.nextArticleId);
      setState(() {});
    }
    if (preArticle != null && page <= preArticle.pageCount - 1) {
      print('<--- 返回上个章节: ${nextArticle.title}');
      nextArticle = curArticle;
      curArticle = preArticle;
      preArticle = null;
      pageIndex = curArticle.pageCount - 1;
      pageController.jumpToPage(curArticle.pageCount - 1);
      loadPreArticle(curArticle.preArticleId);
      setState(() {});
    }
  }

  // 初始化阅读数据
  void setupReaderData() async {
    // 隐藏状态栏，底部虚拟按键
    await SystemChrome.setEnabledSystemUIOverlays([]);
    // 不延迟的话，安卓获取到的topSafeHeight是错的。
    await Future.delayed(const Duration(milliseconds: 100), () {});
    SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.dark);

    topSafeHeight = Screen.topSafeHeight;

    chapters = await Request.getNovelChapters();

    await resetContent(this.widget.articleId, PageJumpType.stay);
  }

  // 重置内容展示 章节 + 页码
  Future<void> resetContent(int articleId, PageJumpType jumpType) async {
    curArticle = await prepareArticle(articleId);
    if (curArticle.preArticleId > 0) {
      preArticle = await prepareArticle(curArticle.preArticleId);
    } else {
      preArticle = null;
    }
    if (curArticle.nextArticleId > 0) {
      nextArticle = await prepareArticle(curArticle.nextArticleId);
    } else {
      nextArticle = null;
    }
    if (jumpType == PageJumpType.firstPage) {
      pageIndex = 0;
    } else if (jumpType == PageJumpType.lastPage) {
      pageIndex = curArticle.pageCount - 1;
    }
    if (jumpType != PageJumpType.stay) {
      pageController.jumpToPage(
          (preArticle != null ? preArticle.pageCount : 0) + pageIndex);
    }
    setState(() {});
  }

  // 加载上一章内容
  Future<void> loadPreArticle(int articleId) async {
    if (preArticle != null || isLoading || articleId == 0) {
      return;
    }
    isLoading = true;
    preArticle = await prepareArticle(articleId);
    pageController.jumpToPage(preArticle.pageCount + pageIndex);
    isLoading = false;
    setState(() {});
  }

  // 加载下一章内容
  Future<void> loadNextArticle(int articleId) async {
    if (nextArticle != null || isLoading || articleId == 0) {
      return;
    }
    isLoading = true;
    nextArticle = await prepareArticle(articleId);
    isLoading = false;
    setState(() {});
  }

  // 解析章节内容数据
  Future<Article> prepareArticle(int articleId) async {
    var article = await Request.getArticle(articleId);
    var contentHeight = Screen.height -
        topSafeHeight -
        Screen.bottomSafeHeight -
        ReaderConfig.topOffset -
        ReaderConfig.bottomOffset -
        20;
    var contentWidth = Screen.width - 15 - 10;
    article.updatePageOffsets(
        contentWidth, contentHeight, ReaderConfig.instance.fontSize);
    return article;
  }
}
